import 'dart:collection';
import 'dart:io';

import 'package:eq/src/bison.dart';
import 'package:eq/src/core.dart';
import 'package:eq/src/interpreter.dart';
import 'package:eq/src/statement.dart';

///主程序调用入口
///要区分主脚本和其他模块
void interpreterCompile(File f, String name) {
  if (!f.existsSync()) {
    exitApp("Error when reading '${f.path}': No such file or directory.", 1);
  }
  // ///搜索的当前pub路径
  // String pub;
  code = f.readAsBytesSync();
  codeLen = code.length;

  Module module = Module(
    f.path,
  );

  ///新建一个模块，命名以文件路径命,其内容将有编译器添加
  ///模块在第一次被调用时编译和注册
  if (yyParse(module)) {
    ///分析完一个文件之后添加模块到编译器
    ///在此分析各个文件的依赖关系
    ///注册进来的模块会调用setup
    Interpreter.getInstance().module.putIfAbsent(name, () => module);
  } else {
    exitApp("Inaccessible area No. 1", 1);
  }
}

///解释语句
///调用函数时才会创建局部变量链表
StatementResult interpreterRun(String module, LinkedList<Statement> list,
    {LinkedList<Variable>? localEnvironment}) {
  StatementResult result = StatementResult();

  if (!Interpreter.getInstance().module.containsKey(module)) {
    result.type = StatementResultType.ERROR_RUNTIME_RESULT;
    result.error = "$module不存在";
    return result;
  }

  for (var s in list) {
    result = executeStatement(module, s, localEnvironment: localEnvironment);
    if (result.type != StatementResultType.NORMAL_STATEMENT_RESULT) break;
  }

  return result;
}

// int _switchdeep = 0;
// int _loopdeep = 0;
StatementResult executeStatement(String module, Statement statement,
    {LinkedList<Variable>? localEnvironment}) {
  StatementResult result = StatementResult();
  switch (statement.type) {
    case StatementType.EXPRESSION_STATEMENT:
      result = expressionStatement(module, statement.expressions,
          localEnvironment: localEnvironment);
      break;
    case StatementType.CONST_STATEMENT:
      result = constStatement(module, statement.consts,
          localEnvironment: localEnvironment);
      break;
    case StatementType.BLOCK_STATEMENT:
      result = blockStatement(module, statement.blocks.block,
          localEnvironment: localEnvironment);
      break;
    case StatementType.IF_STATEMENT:
      result = ifStatement(module, statement.ifs,
          localEnvironment: localEnvironment);
      break;
    case StatementType.WHILE_STATEMENT:
      result = whileStatement(module, statement.whiles,
          localEnvironment: localEnvironment);
      break;
    case StatementType.FOR_STATEMENT:
      result = forStatement(module, statement.fors,
          localEnvironment: localEnvironment);
      break;
    case StatementType.RETURN_STATEMENT:
      result = returnStatement(module, statement.returns,
          localEnvironment: localEnvironment);
      break;
    case StatementType.BREAK_STATEMENT:
      result.type = StatementResultType.BREAK_STATEMENT_RESULT;
      break;
    case StatementType.CONTINUE_STATEMENT:
      result.type = StatementResultType.CONTINUE_STATEMENT_RESULT;
      break;
    case StatementType.SWITCH_STATEMENT:
      result = switchStatement(module, statement.switchs,
          localEnvironment: localEnvironment);
      break;
    case StatementType.TRY_STATEMENT:
      result = tryStatement(module, statement.trys,
          localEnvironment: localEnvironment);
      break;
    case StatementType.STATEMENT_TYPE_COUNT_PLUS_1:
    default:
      result.type = StatementResultType.STATEMENT_RESULT_TYPE_COUNT_PLUS_1;
      result.error = "语句类型错误";
      break;
  }
  return result;
}
